﻿using System;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
using System.Collections.Generic;
using System.Reflection;
using Object = UnityEngine.Object;


using UnityEditor.IMGUI.Controls;
public class MultiColumnTreeView<T> : TreeView
{

    public List<SaveItem> allSaveitem;

    protected Func<T[]> GetItemsCallBack;

    protected Action<T, Rect, int> DrawCellCallBack;

    protected Action<int> Sort;


    public class SaveItem
    {
        public TreeViewItem item;
        public T obj;
    }


    public MultiColumnTreeView(TreeViewState treeViewState, MultiColumnHeader multicolumnHeader, Func<T[]> getItems, Action<T, Rect, int> draw, int rowHeight)
        : base(treeViewState, multicolumnHeader)
    {
        GetItemsCallBack = getItems;
        DrawCellCallBack = draw;
        this.rowHeight = rowHeight;
        if(multicolumnHeader!=null)
            multicolumnHeader.sortingChanged += OnSortingChanged;
        Reload();

    }
    public void ChangeGetItemAndDrawCell(Func<T[]> getItems, Action<T, Rect, int> draw)
    {
        GetItemsCallBack = getItems;
        DrawCellCallBack = draw;
    }
    void OnSortingChanged(MultiColumnHeader multiColumnHeader)
    {
        var rows = GetRows();
        if (rows.Count <= 1)
            return;

        if (multiColumnHeader.sortedColumnIndex == -1)
        {
            return; // No column to sort for (just use the order the data are in)
        }
        var sortedColumns = multiColumnHeader.state.sortedColumns;

        if (sortedColumns.Length == 0)
            return;



        /*var myTypes = rootItem.children.Cast<TreeViewItem<MyTreeElement>>();
        var orderedQuery = InitialOrder(myTypes, sortedColumns);
        for (int i = 1; i < sortedColumns.Length; i++)
        {
            SortOption sortOption = m_SortOptions[sortedColumns[i]];
            bool ascending = multiColumnHeader.IsSortedAscending(sortedColumns[i]);

            switch (sortOption)
            {
                case SortOption.Name:
                    orderedQuery = orderedQuery.ThenBy(l => l.data.name, ascending);
                    break;
                case SortOption.Value1:
                    orderedQuery = orderedQuery.ThenBy(l => l.data.floatValue1, ascending);
                    break;
                case SortOption.Value2:
                    orderedQuery = orderedQuery.ThenBy(l => l.data.floatValue2, ascending);
                    break;
                case SortOption.Value3:
                    orderedQuery = orderedQuery.ThenBy(l => l.data.floatValue3, ascending);
                    break;
            }
        }

        rootItem.children = orderedQuery.Cast<TreeViewItem>().ToList();*/

        if (Sort!=null)
        {
            //Sort(multiColumnHeader,)
        }

        // Sort the roots of the existing tree items
        //SortByMultipleColumns();
        //TreeToList(root, rows);
        Repaint();
    }

    public void ReloadData()
    {
        Reload();
    }


    protected override TreeViewItem BuildRoot()
    {
        var root = new TreeViewItem { id = 0, depth = -1 };

        List<TreeViewItem> allItems = new List<TreeViewItem>();
        allSaveitem = new List<SaveItem>();
        int ids = 0;
        if (GetItemsCallBack != null)
        {
            var items = GetItemsCallBack();
            foreach (var item in items)
            {
                SaveItem saveitem = new SaveItem();
                saveitem.item = new TreeViewItem { id = ids, depth = 1 };
                saveitem.obj = item;
                ids++;
                allItems.Add(saveitem.item);
                allSaveitem.Add(saveitem);
            }
        }

        // Utility method that initializes the TreeViewItem.children and .parent for all items.
        SetupParentsAndChildrenFromDepths(root, allItems);

        // Return root of the tree
        return root;
    }

    protected override void RowGUI(RowGUIArgs args)
    {
        var item = (TreeViewItem)args.item;

        var ele = allSaveitem.Find(obj => obj.item == item);

        for (int i = 0; i < args.GetNumVisibleColumns(); ++i)
        {
            CellGUI(args.GetCellRect(i), ele.obj, args.GetColumn(i), ref args);
        }


    }

    private void CellGUI(Rect cellRect, T item, int column,
            ref RowGUIArgs args)
    {
        DrawCellCallBack(item, cellRect, column);
    }
}
